
#include <Length.h>
#include <stdio.h>
#include <Measurement.h>

#define YARDS_PER_MILE 1760
#define FEET_PER_YARD 3
#define UNITS_PER_FEET 1

const UnitType UnitLength::typeLength;

UnitLength::UnitLength(const int valueInBaseUnit, const UnitType& unitType, const char* unitName)
  : Unit(valueInBaseUnit, unitType, unitName)
{
}

Unit& UnitLength::getMile()
{
    static UnitLength Mile(YARDS_PER_MILE * FEET_PER_YARD, typeLength, "MILE");
    return Mile;
}

Unit& UnitLength::getYard()
{
    static UnitLength Yard(FEET_PER_YARD, typeLength, "YARD");
    return Yard;
}

Unit& UnitLength::getFeet()
{
    static UnitLength Feet(UNITS_PER_FEET, typeLength, "FEET");
    return Feet;
}

Unit& UnitLength::getBaseUnit() const
{
    return getFeet();
}

int UnitLength::formatString(string& strOutput, const int amount, const Unit& unit) const
{
    int result = amount / unit.getValueOfUnit();
    if(result > 0)
    {
        char cstr[256];
        sprintf(cstr, "%d ", result);
        if(!strOutput.empty())
            strOutput += " ";
        strOutput += string(cstr);
        strOutput += unit.getUnitName();
    }

    return amount % unit.getValueOfUnit();
}

string UnitLength::toStandardString(const int amountInBaseUnit) const
{
    if(0 == amountInBaseUnit)
       return "0 FEET";

    string strOutput = "";
    int remainder = formatString(strOutput, amountInBaseUnit, getMile());
    remainder = formatString(strOutput, remainder, getYard());
    formatString(strOutput, remainder, getFeet());

    return strOutput;
}

string UnitLength::toBaseUnitString(const int amountInBaseUnit) const
{
    if(0 == amountInBaseUnit)
       return "0 FEET";

    string strOutput = "";
    formatString(strOutput, amountInBaseUnit, getFeet());
    return strOutput;
}

string UnitLength::toString(const int printModel, const int amountInBaseUnit) const
{
    if(STRING_BASE_UNIT_PRINT_MODE == printModel)
        return toBaseUnitString(amountInBaseUnit);

    return toStandardString(amountInBaseUnit);
}

